using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace SQLitenSupport.UI
{

    /// <summary>
    /// 
    /// </summary>
    public partial class RichTextLineNumbered : UserControl
    {

        #region Events & Objects
        #endregion

        #region Class Constants & Variables
        #endregion

        #region Properties

        /// <summary>
        /// Gets/sets the text associated with this control.
        /// </summary>
        [Category( "Appearance" ),
         Description( "Gets/sets the text associated with this control." )]
        public override string Text
        {

            get { return rtfQuery.Text; }
            set { rtfQuery.Text = value; }

        }

        #endregion

        #region Constructor(s)

        /// <summary>
        /// 
        /// </summary>
        public RichTextLineNumbered()
        {

            // Call Init. method
            InitializeComponent();

            // Associate event handlers for RichTextBox
            this.rtfQuery.Resize += new EventHandler( rtfQuery_Resize );
            this.rtfQuery.VScroll += new EventHandler( rtfQuery_VScroll );
            this.picQueryLineNum.Paint += new PaintEventHandler( picQueryLineNum_Paint );


        }

        #endregion

        #region UI-related Helper Methods

        // Method to draw line numbers in the RT Box
        private void DrawRichTextBoxLineNumbers( Graphics gr )
        {

            // Calculate font heigth as the difference in Y coordinate 
            // between line 2 and line 1
            // Note that the RichTextBox text must have at least two lines. 
            // So the initial Text property of the RichTextBox should not be an 
            // empty string. It could be something like vbcrlf & vbcrlf & vbcrlf 
            Single font_height = rtfQuery.GetPositionFromCharIndex( rtfQuery.GetFirstCharIndexFromLine( 2 ) ).Y -
                                 rtfQuery.GetPositionFromCharIndex( rtfQuery.GetFirstCharIndexFromLine( 1 ) ).Y;

            if (font_height == 0)
                return;

            // Get the first line index and location
            int firstIndex = rtfQuery.GetCharIndexFromPosition( new Point( 0, (int)(gr.VisibleClipBounds.Y + font_height / 13) ) );
            int firstLine = rtfQuery.GetLineFromCharIndex( firstIndex );
            int firstLineY = rtfQuery.GetPositionFromCharIndex( firstIndex ).Y;

            // Print on the PictureBox the visible line numbers of the RichTextBox
            gr.Clear( Color.Gainsboro );

            int count = firstLine;
            Single row;

            do
            {

                row = firstLineY + 2 + font_height * (count - firstLine - 1);

                gr.DrawString( count.ToString(),
                              rtfQuery.Font,
                              Brushes.Black,
                              picQueryLineNum.Width - gr.MeasureString( count.ToString(), rtfQuery.Font ).Width, row );

                count++;

            } while (row < gr.VisibleClipBounds.Y + gr.VisibleClipBounds.Height);

        }

        #endregion

        #region UI-related Event Handlers

        void rtfQuery_Resize( object sender, EventArgs e )
        {

            DrawRichTextBoxLineNumbers( picQueryLineNum.CreateGraphics() );

        }

        void rtfQuery_VScroll( object sender, EventArgs e )
        {

            DrawRichTextBoxLineNumbers( picQueryLineNum.CreateGraphics() );

        }

        void picQueryLineNum_Paint( object sender, PaintEventArgs e )
        {

            DrawRichTextBoxLineNumbers( e.Graphics );

        }

        #endregion

    } // class

} // namespace
